package deltax.common.math
{
    import __AS3__.vec.*;
    import flash.geom.*;

    public class MathUtl extends Object
    {
        public static const IDENTITY_MATRIX3D:Matrix3D = new Matrix3D(MathUtl.Vector.<Number>([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]));
        public static var TEMP_VECTOR3D:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D2:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D3:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D4:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D5:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D6:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D7:Vector3D = new Vector3D();
        public static var TEMP_VECTOR3D8:Vector3D = new Vector3D();
        public static const EMPTY_VECTOR3D:Vector3D = new Vector3D();
        public static const EMPTY_VECTOR3D_WITH_W:Vector3D = new Vector3D(0, 0, 0, 1);
        public static const INVERSE_Y_AXIS:Vector3D = new Vector3D(0, -1, 0);
        public static const IDENTITY_TEXTURE_MATRIX_DATA:Vector.<Number> = MathUtl.Vector.<Number>([1, 0, 0, 0, 0, 1, 0, 0]);
        public static const IDENTITY_TWO_LAYER_TEXTURE_MATRIX_DATA:Vector.<Number> = MathUtl.Vector.<Number>([1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0]);
        public static var TEMP_VECTOR2D:Vector2D = new Vector2D();
        public static var TEMP_VECTOR2D2:Vector2D = new Vector2D();
        public static const EMPTY_VECTOR2D:Vector2D = new Vector2D();
        public static const TEMP_RECTANGLE:Rectangle = new Rectangle();
        public static const TEMP_RECTANGLE2:Rectangle = new Rectangle();
        public static var TEMP_MATRIX3D:Matrix3D = new Matrix3D();
        public static var TEMP_MATRIX3D2:Matrix3D = new Matrix3D();
        public static var TEMP_MATRIX3D3:Matrix3D = new Matrix3D();
        public static var TEMP_QUATERNION:Quaternion = new Quaternion();
        public static var TEMP_QUATERNION2:Quaternion = new Quaternion();
        public static var TEMP_QUATERNION3:Quaternion = new Quaternion();
        public static const DIRUNIT_NUM:uint = 256;
        public static const RADIAN_PER_DIRUNIT:Number = 0.0245437;
        public static const DEGREE_PER_DIRUNIT:Number = 1.40625;
        public static const PIx2:Number = 6.28319;
        public static const PI_div2:Number = 1.5708;
        private static var BEZIER_TEMP_VECTOR3D:Vector3D = new Vector3D();

        public function MathUtl()
        {
            return;
        }// end function

        public static function max(param1:int, param2:int) : int
        {
            return param1 > param2 ? (param1) : (param2);
        }// end function

        public static function min(param1:int, param2:int) : int
        {
            return param1 < param2 ? (param1) : (param2);
        }// end function

        public static function limit(param1:Number, param2:Number, param3:Number) : Number
        {
            if (param3 < param2)
            {
                param3 = param2;
            }
            if (param1 < param2)
            {
                return param2;
            }
            if (param1 > param3)
            {
                return param3;
            }
            return param1;
        }// end function

        public static function limitInt(param1:int, param2:int, param3:int) : int
        {
            if (param3 < param2)
            {
                param3 = param2;
            }
            if (param1 < param2)
            {
                return param2;
            }
            if (param1 > param3)
            {
                return param3;
            }
            return param1;
        }// end function

        public static function randRange(param1:Number, param2:Number) : Number
        {
            return param1 + Math.random() * (param2 - param1);
        }// end function

        public static function aligenUp(param1:uint, param2:uint) : uint
        {
            return param1 ? (uint((param1 - 1) / param2 + 1) * param2) : (0);
        }// end function

        public static function aligenDown(param1:uint, param2:uint) : uint
        {
            return uint(param1 / param2) * param2;
        }// end function

        public static function lineTo(param1:int, param2:int, param3:int, param4:int, param5:Function) : Boolean
        {
            if (!MathUtl.param5(param1, param2))
            {
                return false;
            }
            var _loc_6:int = 0;
            var _loc_7:* = param1;
            var _loc_8:* = param2;
            var _loc_9:* = Math.abs(param3 - param1);
            var _loc_10:* = Math.abs(param4 - param2);
            var _loc_11:* = _loc_9 << 1;
            var _loc_12:* = _loc_10 << 1;
            var _loc_13:* = param3 < param1 ? (-1) : (1);
            var _loc_14:* = param4 < param2 ? (-1) : (1);
            if (_loc_10 > _loc_9)
            {
                while (_loc_8 != param4)
                {
                    
                    if (_loc_6 - _loc_11 < -_loc_10)
                    {
                        _loc_7 = _loc_7 + _loc_13;
                        _loc_6 = _loc_6 + _loc_12;
                    }
                    _loc_8 = _loc_8 + _loc_14;
                    _loc_6 = _loc_6 - _loc_11;
                    if (!MathUtl.param5(_loc_7, _loc_8))
                    {
                        return false;
                    }
                }
            }
            else if (_loc_10 < _loc_9)
            {
                while (_loc_7 != param3)
                {
                    
                    if (_loc_6 - _loc_12 < -_loc_9)
                    {
                        _loc_8 = _loc_8 + _loc_14;
                        _loc_6 = _loc_6 + _loc_11;
                    }
                    _loc_7 = _loc_7 + _loc_13;
                    _loc_6 = _loc_6 - _loc_12;
                    if (!MathUtl.param5(_loc_7, _loc_8))
                    {
                        return false;
                    }
                }
            }
            else
            {
                while (_loc_7 != param3)
                {
                    
                    _loc_8 = _loc_8 + _loc_14;
                    _loc_7 = _loc_7 + _loc_13;
                    if (!MathUtl.param5(_loc_7, _loc_8))
                    {
                        return false;
                    }
                }
            }
            return true;
        }// end function

        public static function bilinearInterpolate(param1:Number, param2:Number, param3:Number, param4:Number, param5:Number, param6:Number) : Number
        {
            var _loc_7:* = param1 * param5 + param2 * (1 - param5);
            var _loc_8:* = param3 * param5 + param4 * (1 - param5);
            return _loc_7 * (1 - param6) + _loc_8 * param6;
        }// end function

        public static function interpolateArray(param1, param2, param3:Number, param4:uint, param5:uint, param6:Function = null, param7:Object = null)
        {
            if (param4 == param5)
            {
                return param1[param4];
            }
            var _loc_8:* = (param2[param5] - param3) / (param2[param5] - param2[param4]);
            if (param6 == null)
            {
                return param1[param4] * _loc_8 + param1[param5] * (1 - _loc_8);
            }
            return MathUtl.param6(param1[param4], param1[param5], _loc_8, param7);
        }// end function

        public static function mulMatrix(param1:Matrix3D, param2:Matrix3D, param3:Matrix3D = null) : Matrix3D
        {
            var _loc_4:* = param1.rawData;
            var _loc_5:* = param2.rawData;
            param3 = param3 || new Matrix3D();
            var _loc_6:* = param3.rawData;
            param3.rawData[0] = _loc_4[0] * _loc_5[0] + _loc_4[1] * _loc_5[4] + _loc_4[2] * _loc_5[8];
            _loc_6[1] = _loc_4[0] * _loc_5[1] + _loc_4[1] * _loc_5[5] + _loc_4[2] * _loc_5[9];
            _loc_6[2] = _loc_4[0] * _loc_5[2] + _loc_4[1] * _loc_5[6] + _loc_4[2] * _loc_5[10];
            _loc_6[4] = _loc_4[4] * _loc_5[0] + _loc_4[5] * _loc_5[4] + _loc_4[6] * _loc_5[8];
            _loc_6[5] = _loc_4[4] * _loc_5[1] + _loc_4[5] * _loc_5[5] + _loc_4[6] * _loc_5[9];
            _loc_6[6] = _loc_4[4] * _loc_5[2] + _loc_4[5] * _loc_5[6] + _loc_4[6] * _loc_5[10];
            _loc_6[8] = _loc_4[8] * _loc_5[0] + _loc_4[9] * _loc_5[4] + _loc_4[10] * _loc_5[8];
            _loc_6[9] = _loc_4[8] * _loc_5[1] + _loc_4[9] * _loc_5[5] + _loc_4[10] * _loc_5[9];
            _loc_6[10] = _loc_4[8] * _loc_5[2] + _loc_4[9] * _loc_5[6] + _loc_4[10] * _loc_5[10];
            _loc_6[12] = _loc_4[12] * _loc_5[0] + _loc_4[13] * _loc_5[4] + _loc_4[14] * _loc_5[8] + _loc_5[12];
            _loc_6[13] = _loc_4[12] * _loc_5[1] + _loc_4[13] * _loc_5[5] + _loc_4[14] * _loc_5[9] + _loc_5[13];
            _loc_6[14] = _loc_4[12] * _loc_5[2] + _loc_4[13] * _loc_5[6] + _loc_4[14] * _loc_5[10] + _loc_5[14];
            param3.rawData = _loc_6;
            return param3;
        }// end function

        public static function dirIndexToVector(param1:uint, param2:Point = null) : Point
        {
            var _loc_3:* = param1 * RADIAN_PER_DIRUNIT;
            if (!param2)
            {
                param2 = new Point(Math.sin(_loc_3), Math.cos(_loc_3));
            }
            else
            {
                param2.setTo(Math.sin(_loc_3), Math.cos(_loc_3));
            }
            return param2;
        }// end function

        public static function vectorToDirIndex(param1:Point) : uint
        {
            var _loc_3:uint = 0;
            var _loc_2:* = param1.length;
            if (_loc_2 < 1e-005)
            {
                return 0;
            }
            TEMP_VECTOR2D.copyFrom(param1);
            TEMP_VECTOR2D.normalize(1);
            _loc_3 = Math.asin(Math.abs(TEMP_VECTOR2D.x)) / RADIAN_PER_DIRUNIT;
            if (TEMP_VECTOR2D.y < 0)
            {
                _loc_3 = uint(128 - _loc_3) & 255;
            }
            if (TEMP_VECTOR2D.x < 0)
            {
                _loc_3 = uint(-_loc_3) & 255;
            }
            return _loc_3;
        }// end function

        public static function bezierInterpolate3D(param1:Vector3D, param2:Vector3D, param3:Vector3D, param4:Vector3D, param5:Number, param6:Vector3D = null) : Vector3D
        {
            var _loc_7:* = 1 - param5;
            var _loc_8:* = param5 * param5;
            var _loc_9:* = _loc_7 * _loc_7;
            if (!param6)
            {
                param6 = new Vector3D();
            }
            param6.copyFrom(param1);
            param6.scaleBy(_loc_9 * _loc_7);
            BEZIER_TEMP_VECTOR3D.copyFrom(param2);
            BEZIER_TEMP_VECTOR3D.scaleBy(3 * _loc_9 * param5);
            param6.incrementBy(BEZIER_TEMP_VECTOR3D);
            BEZIER_TEMP_VECTOR3D.copyFrom(param3);
            BEZIER_TEMP_VECTOR3D.scaleBy(3 * _loc_8 * _loc_7);
            param6.incrementBy(BEZIER_TEMP_VECTOR3D);
            BEZIER_TEMP_VECTOR3D.copyFrom(param4);
            BEZIER_TEMP_VECTOR3D.scaleBy(_loc_8 * param5);
            param6.incrementBy(BEZIER_TEMP_VECTOR3D);
            return param6;
        }// end function

        public static function catmullRomSpline(param1:Vector3D, param2:Vector3D, param3:Vector3D, param4:Vector3D, param5:Number, param6:Vector.<Vector3D> = null) : Vector3D
        {
            var _loc_7:* = new Vector3D();
            new Vector3D().copyFrom(param3);
            _loc_7.decrementBy(param1);
            _loc_7.scaleBy(0.5);
            var _loc_8:* = new Vector3D();
            var _loc_9:* = new Vector3D();
            _loc_8.copyFrom(param1);
            _loc_9.copyFrom(param2);
            _loc_9.scaleBy(-2.5);
            _loc_8.incrementBy(_loc_9);
            _loc_9.copyFrom(param3);
            _loc_9.scaleBy(2);
            _loc_8.incrementBy(_loc_9);
            _loc_9.copyFrom(param4);
            _loc_9.scaleBy(-0.5);
            _loc_8.incrementBy(_loc_9);
            var _loc_10:* = new Vector3D();
            new Vector3D().copyFrom(param1);
            _loc_10.scaleBy(-0.5);
            _loc_9.copyFrom(param2);
            _loc_9.scaleBy(1.5);
            _loc_10.incrementBy(_loc_9);
            _loc_9.copyFrom(param3);
            _loc_9.scaleBy(-1.5);
            _loc_10.incrementBy(_loc_9);
            _loc_9.copyFrom(param4);
            _loc_9.scaleBy(0.5);
            _loc_10.incrementBy(_loc_9);
            if (param6)
            {
                param6[0].copyFrom(param2);
                param6[1].copyFrom(_loc_7);
                param6[2].copyFrom(_loc_8);
                param6[3].copyFrom(_loc_10);
            }
            _loc_9.copyFrom(_loc_10);
            _loc_9.scaleBy(param5);
            _loc_9.incrementBy(_loc_8);
            _loc_9.scaleBy(param5);
            _loc_9.incrementBy(_loc_7);
            _loc_9.scaleBy(param5);
            _loc_9.incrementBy(param2);
            return _loc_9;
        }// end function

        public static function wrapToUpperPowerOf2(param1:int) : int
        {
            var _loc_2:* = Math.ceil(Math.log(param1) / Math.LN2);
            return Math.pow(2, _loc_2);
        }// end function

        public static function maxVector3D(param1:Vector3D, param2:Vector3D, param3:Vector3D = null) : Vector3D
        {
            if (!param3)
            {
                param3 = new Vector3D();
            }
            param3.x = Math.max(param1.x, param2.x);
            param3.y = Math.max(param1.y, param2.y);
            param3.z = Math.max(param1.z, param2.z);
            return param3;
        }// end function

        public static function minVector3D(param1:Vector3D, param2:Vector3D, param3:Vector3D = null) : Vector3D
        {
            if (!param3)
            {
                param3 = new Vector3D();
            }
            param3.x = Math.min(param1.x, param2.x);
            param3.y = Math.min(param1.y, param2.y);
            param3.z = Math.min(param1.z, param2.z);
            return param3;
        }// end function

        public static function unionRectangleBy(param1:Rectangle, param2:Rectangle, param3:Rectangle = null) : Rectangle
        {
            if (!param3)
            {
                param3 = new Rectangle();
            }
            if (param2.isEmpty())
            {
                param3.copyFrom(param1);
                return param1;
            }
            param3.left = Math.min(param1.left, param2.left);
            param3.right = Math.max(param1.right, param2.right);
            param3.top = Math.min(param1.top, param2.top);
            param3.bottom = Math.max(param1.bottom, param2.bottom);
            return param3;
        }// end function

    }
}
